<script setup>
import { ref, nextTick, onMounted } from "vue";
import { Plus } from "@element-plus/icons-vue";
import {
  roleMgrUpdateStatusService,
  roleMgrAddService,
  roleMgrUpdateService,
  roleMgrMenuService,
  roleMgrSaveService,
} from "@/api";
import { useUserStore } from "@/stores";

// 使用用户存储模块
const userInfo = useUserStore();

// 抽屉的可见性状态
const visibleDrawer = ref(false);

// 默认表单数据
const defaultForm = {
  id: "",
  roleCode: "",
  roleName: "",
  description: "",
  status: 0,
  createTime: "",
  updateTime: "",
};

// 表单模型，用于数据绑定和操作
const formModel = ref({ ...defaultForm });

// 角色操作标志，用于区分功能
let roleOperation = ref(false);

// 表单规则
const rules = {
  roleName: [{ required: true, message: "请输入角色名称", trigger: "blur" }],
  roleCode: [
    { required: true, message: "请输入角色代码", trigger: "blur" },
    {
      pattern: /^[^\u4e00-\u9fa5\s]{4,}$/,
      message: "请输入一个至少4个字符,不包含中文或空格的用户名。",
      trigger: "blur",
    },
  ],
  description: [{ required: true, message: "请输入描述", trigger: "blur" }],
};

// 打开抽屉函数------start
let titleDrawer = ref("编辑用户");
let operateStatus = ref("edit");
let loadingRoleTree = ref(false);

/**
 * 打开抽屉函数，根据传入的行数据和操作类型，决定是编辑、添加还是角色分配操作
 * @param {Object} row - 行数据
 * @param {String} operate - 操作类型
 */
const open = async (row, operate) => {
  console.log(row);
  operateStatus.value = operate;
  visibleDrawer.value = true;
  if (operate == "edit") {
    formModel.value = row;
    roleOperation.value = false;
    titleDrawer.value = "编辑角色";
  }
  if (operate == "add") {
    roleOperation.value = true;
    formModel.value = { ...defaultForm };
    titleDrawer.value = "添加角色";
  }
  if (operate == "role") {
    titleDrawer.value = "分配功能";
    formModel.value = row;
    roleOperation.value = true;
    getAssignRoleTree(row.id);
  }
};
defineExpose({ open });
// 打开抽屉函数------end

// 切换用户状态-----start
// 加载状态的ref对象，用于状态切换的动画
let loadingStatus = ref(false);

/**
 * 异步函数，用于处理用户状态更改
 * @param {Object} row - 包含行数据的对象，此对象应包含状态和ID属性
 * @returns {Promise}
 */
const onStatusChange = async () => {
  try {
    loadingStatus.value = true;
    // 根据当前行的状态，重新转回1、0
    let status = formModel.value.status == false ? 0 : 1;
    await roleMgrUpdateStatusService(formModel.value.id, status);
    ElMessage.success("修改成功");
  } catch (error) {
    row.status = !row.status;
    ElMessage.error("修改失败");
  } finally {
    loadingStatus.value = false;
  }
};
// 切换用户状态-----end

// 定义菜单树组件的默认属性
const defaultProps = {
  children: "children", // 子节点的键名
  label: "name", // 节点显示文本的键名
};

let roleTreeData = ref([]); // 角色树形数据的引用
let defaultCheckedTreeKeys = ref([]); // 默认选中的树形节点键名的引用
let checkedKeys = ref([...defaultCheckedTreeKeys.value]); // 选中节点的id

/**
 * 根据角色ID异步获取并加载角色菜单树
 * @param {string} id - 角色的ID，用于查询其关联的菜单
 */
const getAssignRoleTree = async (id) => {
  loadingRoleTree.value = true;
  try {
    let { data } = await roleMgrMenuService(id);
    console.log(data);
    // 更新角色树形数据
    roleTreeData.value = data;
    // 递归获取所有选中的节点
    const getAllCheckedKeys = (data) => {
      let keys = [];
      data.forEach((item) => {
        if (item.select && item.children.length == 0) {
          keys.push(item.id);
        }
        if (item.children.length > 0) {
          keys = keys.concat(getAllCheckedKeys(item.children));
        }
      });
      return keys;
    };
    console.log(getAllCheckedKeys(data));
    // 更新默认选中的树形节点
    defaultCheckedTreeKeys.value = getAllCheckedKeys(data);
    // defaultCheckedTreeKeys.value = [8, 9, 86];
  } catch (error) {
    console.log(error);
  } finally {
    loadingRoleTree.value = false;
  }
};
/**
 * 当检查状态发生变化时的处理函数。
 * 共两个参数，依次为：传递给 data 属性的数组中该节点所对应的对象、树目前的选中状态对象，包含 checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys 四个属性
 * @param {Object} event - 触发改变的事件对象，此处未使用。
 * @param {Object} status - 包含已选中节点键的状态对象。
 * @returns {void} 不返回任何内容。
 */

//  toods 要传回父菜单的id
const onCheckChange = (event, status) => {
  let checkedKey = [...status.checkedKeys, ...status.halfCheckedKeys];
  checkedKeys.value = checkedKey; // 更新 checkedKeys 的值为当前已检查的键
};

// 添加或编辑操作-------start

let loadingAdd = ref(false); // 添加和编辑操作的加载状态
const formRef = ref(); // 表单引用，用于表单验证和提交

// 发送到父组件的成功事件
const emit = defineEmits(["success"]);

/**
 * 提交表单数据，根据是否有ID判断是进行编辑还是添加操作
 * @param {String} state - 表单状态（已发布或草稿）
 */
const onSubmit = async (state) => {
  await formRef.value.validate(); // 验证表单
  loadingAdd.value = true;
  try {
    if (operateStatus.value == "edit") {
      console.log("编辑操作");
      // 将status转回1/0
      formModel.value.status = formModel.value.status == false ? 0 : 1;
      await roleMgrUpdateService(formModel.value);
      ElMessage.success("编辑成功");
      visibleDrawer.value = false;
      emit("success", "edit");
    }

    if (operateStatus.value == "add") {
      // 添加请求
      let res = await roleMgrAddService(formModel.value);
      console.log(res);
      ElMessage.success("添加成功");
      visibleDrawer.value = false;
      emit("success", "add");
    }
    if (operateStatus.value == "role") {
      // 分配角色请求
      // let menuIdList = [];
      let menuIdList = checkedKeys.value.map((item) => {
        // let arr = {
        //   id: item,
        //   isHalf: 0,
        // };
        return +item;
      });
      // console.log(checkedKeys.value);
      let roleData = {
        menuIdList,
        roleId: formModel.value.id,
      };
      let res = await roleMgrSaveService(roleData);
      console.log(res);
      ElMessage.success("分配成功");
      visibleDrawer.value = false;
      emit("success", "role");
    }
  } catch (error) {
    formModel.value.status = formModel.value.status == 0 ? false : true;
    console.log(error);
  } finally {
    loadingAdd.value = false;
  }
};
// 添加或编辑操作-------end
</script>

<template>
  <!-- 抽屉组件，用于编辑和添加用户 -->
  <el-drawer
    v-model="visibleDrawer"
    :title="titleDrawer"
    direction="rtl"
    size="60%"
    style="padding: 30px"
  >
    <!-- 表单组件，用于输入信息 -->
    <el-form
      :model="formModel"
      ref="formRef"
      :rules="rules"
      label-width="100px"
      label-position="top"
    >
      <el-form-item label="角色名称" prop="roleName">
        <el-input
          v-model="formModel.roleName"
          placeholder="请输入角色名称"
          :disabled="formModel.id != '' && roleOperation"
        ></el-input>
      </el-form-item>
      <el-form-item label="角色代码" prop="roleCode">
        <el-input
          v-model="formModel.roleCode"
          placeholder="请输入角色代码"
          :disabled="formModel.id != '' && roleOperation"
        ></el-input>
      </el-form-item>

      <el-form-item label="描述" prop="description">
        <el-input
          v-model="formModel.description"
          placeholder="请输入描述"
          :disabled="formModel.id != '' && roleOperation"
        ></el-input>
      </el-form-item>

      <!-- 用户状态切换开关，仅在编辑操作时显示 -->
      <el-form-item label="状态" prop="status" v-if="!roleOperation">
        <el-switch
          v-model="formModel.status"
          :loading="loadingStatus"
          @change="onStatusChange()"
        />
      </el-form-item>
      <el-form-item label="菜单分配" v-if="operateStatus == 'role'">
        <el-tree
          v-loading="loadingRoleTree"
          style="max-width: 600px"
          :data="roleTreeData"
          show-checkbox
          node-key="id"
          default-expand-all
          check-on-click-node
          :default-checked-keys="defaultCheckedTreeKeys"
          :props="defaultProps"
          @check="onCheckChange"
        >
          <template #empty> <el-empty description="没有数据" /> </template
        ></el-tree>
      </el-form-item>

      <!-- 提交表单按钮 -->
      <el-form-item>
        <el-button
          type="primary"
          :icon="Plus"
          :loading="loadingAdd"
          @click="onSubmit('已发布')"
          >提交</el-button
        >
      </el-form-item>
    </el-form>
  </el-drawer>
</template>

<style scoped lang="scss">
.avatar-uploader {
  :deep() {
    .avatar {
      width: 178px;
      height: 178px;
      display: block;
    }
    .el-upload {
      border: 1px dashed var(--el-border-color);
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      transition: var(--el-transition-duration-fast);
    }
    .el-upload:hover {
      border-color: var(--el-color-primary);
    }
    .el-icon.avatar-uploader-icon {
      font-size: 28px;
      color: #8c939d;
      width: 178px;
      height: 178px;
      text-align: center;
    }
  }
}
.editor {
  width: 100%;
  :deep(.ql-editor) {
    min-height: 200px;
  }
}
.el-input {
  max-width: 500px;
}
</style>
